import hashlib
from django.core.cache import cache
from django.core.files.uploadhandler import FileUploadHandler, TemporaryFileUploadHandler, MemoryFileUploadHandler
import time

__author__ = 'KJS'

class ProgressBarFileUploadHandler(FileUploadHandler):

    def __init__(self, request=None, upload_hash_key=None):
        super(ProgressBarFileUploadHandler, self).__init__(request)
        self.is_progress_record = False
        self.upload_hash = None
        self.upload_hash_key = 'uploadhash'
        if upload_hash_key:
            self.upload_hash_key = upload_hash_key

    def new_file(self, field_name, file_name, content_type, content_length, charset=None):
        super(ProgressBarFileUploadHandler, self).new_file(field_name, file_name, content_type, content_length,
            charset)

    def receive_data_chunk(self, raw_data, start):
        if self.is_progress_record:
            uploaded = cache.get(self.upload_hash)
            if uploaded:
                uploaded['uploadedLength'] = len(raw_data) + start
                cache.set(self.upload_hash, uploaded)
            time.sleep(0.2)
        return raw_data

    def handle_raw_input(self, input_data, META, content_length, boundary, encoding=None):
        super(ProgressBarFileUploadHandler, self).handle_raw_input(input_data, META, content_length, boundary,
            encoding)
        if input_data.GET and self.upload_hash_key in input_data.GET:
            self.is_progress_record = True
            self.upload_hash = str(input_data.GET.get(self.upload_hash_key)).strip()
            uploaded = {
                'contentLength':content_length,
                'uploadCompleted':0,
                'uploadedLength':0
            }
            cache.set(self.upload_hash, uploaded)

    def upload_complete(self):
        self.uploaded = cache.get(self.upload_hash)
        if self.uploaded:
            self.uploaded['uploadCompleted'] = 1
            cache.set(self.upload_hash, self.uploaded, 10*60)
        super(ProgressBarFileUploadHandler, self).upload_complete()

    def file_complete(self, file_size):
        return

class ContentTypeCheckFileUploadHandler(FileUploadHandler):

    def new_file(self, field_name, file_name, content_type, content_length, charset=None):
        super(ContentTypeCheckFileUploadHandler, self).new_file(field_name, file_name, content_type, content_length,
            charset)

    def receive_data_chunk(self, raw_data, start):
        return raw_data

    def handle_raw_input(self, input_data, META, content_length, boundary, encoding=None):
        super(ContentTypeCheckFileUploadHandler, self).handle_raw_input(input_data, META, content_length, boundary,
            encoding)

    def upload_complete(self):
        super(ContentTypeCheckFileUploadHandler, self).upload_complete()

    def file_complete(self, file_size):
        return


class RainbowImageTemporaryFileUploadHandler(TemporaryFileUploadHandler):
    def __init__(self, *args, **kwargs):
        super(RainbowImageTemporaryFileUploadHandler, self).__init__(*args, **kwargs)
        self.content_md5 = None

    def new_file(self, file_name, *args, **kwargs):
        super(RainbowImageTemporaryFileUploadHandler, self).new_file(file_name, *args, **kwargs)
        self.content_md5 = hashlib.md5()

    def receive_data_chunk(self, raw_data, start):
        super(RainbowImageTemporaryFileUploadHandler, self).receive_data_chunk(raw_data, start)
        self.content_md5.update(raw_data)

    def file_complete(self, file_size):
        f = super(RainbowImageTemporaryFileUploadHandler, self).file_complete(file_size)
        f.content_md5 = self.content_md5.hexdigest()
        self.content_md5 = None
        return f

class RainbowImageMemoryFileUploadHandler(MemoryFileUploadHandler):
    def __init__(self, *args, **kwargs):
        super(RainbowImageMemoryFileUploadHandler, self).__init__(*args, **kwargs)
        self.content_md5 = None

    def new_file(self, file_name, *args, **kwargs):
        super(RainbowImageMemoryFileUploadHandler, self).new_file(file_name, *args, **kwargs)
        self.content_md5 = hashlib.md5()

    def receive_data_chunk(self, raw_data, start):
        super(RainbowImageMemoryFileUploadHandler, self).receive_data_chunk(raw_data, start)
        self.content_md5.update(raw_data)

    def file_complete(self, file_size):
        f = super(RainbowImageMemoryFileUploadHandler, self).file_complete(file_size)
        f.content_md5 = self.content_md5.hexdigest()
        self.content_md5 = None
        return f

